home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Devices and Hardware / SCSI / SCSI DriveID Sample / ShowSCSIDeviceIdent.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  4.9 KB  |  190 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ShowSCSIDeviceIdent.c
  3.  
  4.     Contains:    This subroutine prints the bus ID or device ident associated with the
  5.                  specified driver.
  6.  
  7.     Written by: Martin Minow    
  8.  
  9.     Copyright:    Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved.
  10.  
  11.                 You may incorporate this Apple sample source code into your program(s) without
  12.                 restriction. This Apple sample source code has been provided "AS IS" and the
  13.                 responsibility for its operation is yours. You are not permitted to redistribute
  14.                 this Apple sample source code as "Apple sample source code" after having made
  15.                 changes. If you're going to re-distribute the source, we require that you make
  16.                 it clear in the source that the code was descended from Apple sample source
  17.                 code, but that you've made changes.
  18.  
  19.     Change History (most recent first):
  20.                 7/14/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  21.                 
  22.  
  23. */
  24. #include <stdio.h>
  25. #include <Files.h>
  26. #include <Devices.h>
  27. #include <Memory.h>
  28. #ifndef FALSE
  29. #define FALSE        0
  30. #define TRUE        1
  31. #endif
  32. /*
  33.  * Include the O.S. files in a specific order to make sure that we have
  34.  * a definition for the _SCSIAtomic trap.
  35.  */
  36. #include <Traps.h>
  37. #ifndef _SCSIAtomic
  38. #define _SCSIAtomic    0xA089
  39. #endif
  40. /*
  41.  * Note that this uses a later version of <Scsi.h> than is available in
  42.  * the published headers.
  43.  */
  44. #include "Scsi.h"
  45.  
  46. void                    ShowSCSIDeviceIdent(
  47.         short                driverRefNum
  48.     );
  49. Boolean                    AsyncSCSIPresent(void);
  50.  
  51. static void
  52. ClearMemory(
  53.         Ptr                ptr,
  54.         Size            size
  55.     )
  56. {
  57.         while (size > 0) {
  58.             *ptr++ = 0;
  59.             --size;
  60.         }
  61. }
  62.  
  63. /*
  64.  * The following macros are valid for the old SCSI Manager and for SCSI Manager
  65.  * 4.3 in the simple case where the device is the first registered on a bus
  66.  * and is registered under logical unit zero.
  67.  */
  68. #define DriverRefNumToSCSI(x)    ((signed short) (~(x) - 32))
  69. /*
  70.  * This macro converts a SCSI bus ID to a DriverRefNum
  71.  */
  72. #define SCSIToDriverRefNum(x)    ((signed short) (~((x) + 32)))
  73. /*
  74.  * These constants define the range of Driver RefNum's that are associated with
  75.  * hard-wired SCSI bus id's. Note that the driver reference numbers are negative.
  76.  * If a driver is present in this range, the device can be accessed through both
  77.  * the old and New SCSI Manager.
  78.  */
  79. #define kMinSCSIDrive    (SCSIToDriverRefNum(6))
  80. #define kMaxSCSIDrive    (SCSIToDriverRefNum(0))
  81.  
  82. Boolean                        IsHardWiredSCSIDevice(
  83.         register short            driverRefNum
  84.     );
  85. Boolean                        DriverRefNumToDeviceIdent(
  86.         register short            driverRefNum,
  87.         DeviceIdent                *deviceIdentPtr
  88.     );
  89.  
  90. void
  91. ShowSCSIDeviceIdent(
  92.         short                driverRefNum
  93.     )
  94. {
  95.         DeviceIdent            deviceIdent;
  96.         
  97.         if (DriverRefNumToDeviceIdent(driverRefNum, &deviceIdent)) {
  98.             /*
  99.              * This device is registered with SCSI Manager 4.3
  100.              */
  101.             printf(
  102.                 " -- [%d.%d.%d] (registered)",
  103.                 (int) deviceIdent.bus,
  104.                 (int) deviceIdent.targetID,
  105.                 (int) deviceIdent.LUN
  106.             );
  107.         }
  108.         else if (IsHardWiredSCSIDevice(driverRefNum)) {
  109.             /*
  110.              * This is a SCSI device whose driver did not register
  111.              * with SCSI Manager 4.3, possibly because the new
  112.              * SCSI Manager is not installed on this machine.
  113.              */
  114.             printf(" -- [%d] (hardwired)",
  115.                 (int) DriverRefNumToSCSI(driverRefNum));
  116.         }
  117.         else {
  118.             /*
  119.              * This is not a SCSI device.
  120.              */
  121.             printf(" -- Not SCSI");
  122.         }
  123. }
  124.  
  125. /*
  126.  * If SCSI Manager 4.3 is present and this driver has been registered, return
  127.  * TRUE and store the SCSI Device Ident in the deviceIdentPtr location. If SCSI
  128.  * Manager 4.3 is not present, or this is not a registered driver, return FALSE.
  129.  *
  130.  * Note that this returns FALSE even if SCSI Manager 4.3 is present if the
  131.  * device's driver did not register with the new SCSI Manager (i.e. if the
  132.  * device uses an "old-style" driver).
  133.  */
  134. Boolean
  135. DriverRefNumToDeviceIdent(
  136.         register short            driverRefNum,
  137.         DeviceIdent                *deviceIdentPtr
  138.     )
  139. {
  140.         SCSIDriverPB            pb;
  141.         OSErr                    status;
  142.         
  143.         if (AsyncSCSIPresent()) {
  144.             ClearMemory((Ptr) &pb, sizeof pb);
  145.             pb.scsiPBLength = sizeof (SCSIDriverPB);
  146.             pb.scsiCompletion = NULL;
  147.             pb.scsiFlags = 0;
  148.             pb.scsiFunctionCode = SCSILookupRefNumXref;
  149.             * ((long *) &pb.scsiDevice) = 0xFFFFFFFFL;
  150.             do {
  151.                 status = SCSIAction((SCSI_PB *) &pb);
  152.                 if (status != noErr)
  153.                     break;
  154.                 else if (pb.scsiDriver == driverRefNum
  155.                       && pb.scsiDevice.bus != 0xFF) {
  156.                     *deviceIdentPtr = pb.scsiDevice;
  157.                     return (TRUE);                        /* Success                */
  158.                 }
  159.                 else {
  160.                     pb.scsiDevice = pb.scsiNextDevice;
  161.                 }
  162.             }
  163.             while (pb.scsiDevice.bus != 0xFF);
  164.         }
  165.         /*
  166.          * Exit here if either the New SCSI Manager is no present or
  167.          * the device is not a SCSI device.
  168.          */
  169.          return (FALSE);
  170. }
  171.  
  172.                 
  173.  
  174. /*
  175.  * TRUE if this driver is a SCSI device. Note: this is valid only for the Old SCSI
  176.  * Manager and for the New SCSI Manager in a simple bus configuration where all
  177.  * devices have unique target ID's and all SCSI devices are at logical unit zero.
  178.  */
  179. Boolean
  180. IsHardWiredSCSIDevice(
  181.         register short            driverRefNum
  182.     )
  183. {
  184.         return (
  185.             DriverRefNumToSCSI(driverRefNum) >= 0
  186.             && DriverRefNumToSCSI(driverRefNum) <= 6
  187.         );
  188. }
  189.  
  190.